﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;
using System.IO;

namespace Tools
{
    /// <summary>
    /// XML常见操作
    /// </summary>
    public class XmlUtil
    {
        /// <summary>
        /// 得到XML节点的属性的值，如果不存在，则返回空
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attribute"></param>
        /// <returns></returns>
        public static string GetXmlAttribute(XmlNode node, string attribute)
        {
            XmlAttribute rtn = node.Attributes[attribute];
            if (rtn == null)
                return null;
            else
                return rtn.InnerText;
        }

        /// <summary>
        /// Gets the value of the specified XmlNode.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static string GetValue(XmlNode node)
        {
            try
            {
                return node.FirstChild.Value;
            }
            catch //(Exception ex)
            {
                return null;
            }
        }


        /// <summary>
        /// Gets the specified attribute from the specified XmlNode.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attName"></param>
        /// <returns></returns>
        public static string GetAttribute(XmlNode node, string attName)
        {
            try
            {
                return node.Attributes.GetNamedItem(attName).Value;
            }
            catch //(Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// Checks that if the XmlNode has a value.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool HasValue(XmlNode node)
        {
            try
            {
                string val = node.FirstChild.Value;
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Checks that if the XmlNode has the specified attribute.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attName"></param>
        /// <returns></returns>
        public static bool HasAttribute(XmlNode node, string attName)
        {
            try
            {
                string attribute = node.Attributes.GetNamedItem(attName).Value;
                return true;
            }
            catch
            {
                return false;
            }
        }

        //2009-12-1增加以下代码

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static XmlNode AddAttribute(XmlNode rootNode, string name, int value)
        {
            return AddAttribute(rootNode, name, value.ToString());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static XmlNode AddAttribute(XmlNode rootNode, string name, string value)
        {
            XmlAttribute node = rootNode.OwnerDocument.CreateAttribute(name);
            node.Value = value;
            rootNode.Attributes.SetNamedItem(node);
            return rootNode;
        }

        //public static void AddNodeFromFile(XmlNode rootNode, FilenameProcessor filename, string nodetoadd)
        //{
        //    if ((rootNode != null) && filename.getContext().getXMLDataBase().existsDocument(filename.FullQualifiedName()))
        //    {
        //        try
        //        {
        //            foreach (XmlNode node in filename.getContext().getXMLDataBase().getDocument(filename.FullQualifiedName()).SelectSingleNode(nodetoadd).ChildNodes)
        //            {
        //                XmlNode newChild = rootNode.OwnerDocument.ImportNode(node, true);
        //                rootNode.AppendChild(newChild);
        //            }
        //        }
        //        catch (Exception exception)
        //        {
        //            throw exception;
        //        }
        //    }
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="nodeToAdd"></param>
        public static void AddNodeFromNode(XmlNode source, XmlNode nodeToAdd)
        {
            if (nodeToAdd == null) return;
            foreach (XmlNode node in nodeToAdd.ChildNodes)
            {
                XmlNode newChild = source.OwnerDocument.ImportNode(node, true);
                source.AppendChild(newChild);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xnode"></param>
        /// <param name="name"></param>
        public static void RemoveAttribute(XmlNode xnode, string name)
        {
            XmlAttribute xattrib = xnode.Attributes[name];
            if (xattrib != null) xnode.Attributes.Remove(xattrib);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        public static XmlNamespaceManager GetNamespaces(XmlDocument doc)
        {
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new
                NameTable());
            System.Xml.XPath.XPathNavigator nav2 = doc.DocumentElement.CreateNavigator();
            if (nav2.MoveToFirstNamespace())
            {
                do
                {
                    if (!nav2.Name.StartsWith("xml"))
                    {
                        namespaceManager.AddNamespace(nav2.Name, nav2.Value);
                    }
                } while (nav2.MoveToNextNamespace());
            }
            return namespaceManager;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="text"></param>
        public static void AddTextNode(XmlNode rootNode, string text)
        {
            if (text != "")
            {
                XmlNode newChild = rootNode.OwnerDocument.CreateTextNode(text);
                rootNode.AppendChild(newChild);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="nodeName"></param>
        /// <param name="nodeText"></param>
        /// <returns></returns>
        public static XmlNode CreateChild(XmlNode rootNode, string nodeName, string nodeText)
        {
            XmlNode node = rootNode.OwnerDocument.CreateNode(XmlNodeType.Element, nodeName, "");
            AddTextNode(node, nodeText);
            rootNode.AppendChild(node);
            return node;
        }

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public static bool RemoveChild(XmlNode rootNode, string xpath)
        {
            XmlNodeList list = rootNode.SelectNodes(xpath);
            if (list == null)
                return false;
            foreach (XmlNode n in list)
            {
                n.ParentNode.RemoveChild(n);
            }

            return true;
        }

        /// <summary>
        /// 节点替换
        /// </summary>
        /// <param name="oldNode"></param>
        /// <param name="newNode"></param>
        /// <returns></returns>
        public static bool ReplaceChild(XmlNode oldNode, XmlNode newNode)
        {
            if (oldNode == null || newNode == null)
                return false;

            oldNode.ParentNode.ReplaceChild(newNode, oldNode);
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rootNode"></param>
        /// <param name="nodeName"></param>
        /// <param name="nodeText"></param>
        /// <returns></returns>
        public static XmlNode CreateChildBefore(XmlNode rootNode, string nodeName, string nodeText)
        {
            XmlNode node = rootNode.OwnerDocument.CreateNode(XmlNodeType.Element, nodeName, "");
            AddTextNode(node, nodeText);
            rootNode.InsertBefore(node, rootNode.ChildNodes.Item(0));
            return node;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static XmlDocument CreateXmlDocument()
        {
            XmlDocument document = new XmlDocument();
            document.XmlResolver = null;
            XmlNode newChild = document.CreateNode(XmlNodeType.XmlDeclaration, "", "");
            document.AppendChild(newChild);
            return document;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static XmlDocument CreateXmlDocument(string filename)
        {
            XmlDocument document = new XmlDocument();
            document.Load(filename);
            return document;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static XmlDocument CreateXmlDocumentFromStr(string xml)
        {
            XmlDocument document = new XmlDocument();
            document.XmlResolver = null;
            document.LoadXml(xml.Replace("&", "&amp;"));
            return document;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static string GetFormattedDocument(XmlDocument xml)
        {
            byte[] buffer;
            MemoryStream w = new MemoryStream();
            try
            {
                XmlTextWriter writer = new XmlTextWriter(w, null);
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 3;
                writer.IndentChar = ' ';
                try
                {
                    xml.Save(writer);
                }
                finally
                {
                    writer.Close();
                }
                buffer = w.ToArray();
            }
            finally
            {
                w.Close();
            }
            return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
        }
    }
}
